/**
 * Copyright (c) 2010-2011 Pierre Labatut
 *
 * This file is part of Space-Chronicles project.
 *
 * Space-Chronicles is free software: you can redistribute it and/or modify it
 * under the terms of its license which may be found in the accompanying
 * LICENSE file or <http://code.google.com/p/space-chronicles/>.
 */
package space.game.config;

import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.io.File;
import java.io.FilenameFilter;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Mixer;
import net.java.games.input.Controller;
import net.java.games.input.ControllerEnvironment;
import space.input.FilePlayControler;

/**
 *
 * @author Pierre
 */
class CfgPreference {

    private final String gfxDevice;
    private final String gfxMode;
    private final boolean gfxFullScreen;
    private final String sfxMixer;
    private final String ctrlDevice;
    private final boolean cfgShowPanel;

    private CfgPreference(String gfxDevice, String gfxMode, boolean gfxFullScreen, String mixerInfo, String ctrlDevice, boolean cfgShowPanel) {
        this.gfxDevice = gfxDevice;
        this.gfxMode = gfxMode;
        this.gfxFullScreen = gfxFullScreen;
        this.sfxMixer = mixerInfo;
        this.ctrlDevice = ctrlDevice;
        this.cfgShowPanel = cfgShowPanel;
    }

    CfgPreference(GraphicsDevice gfxDevice, DisplayMode gfxMode, boolean gfxFullScreen, Mixer.Info mixerInfo, Controller ctrlDevice, boolean cfgShowPanel) {
        this(gfxDevice.getIDstring(),
                gfxMode != null ? new CfgDisplayMode(gfxMode).toString() : null,
                gfxFullScreen,
                mixerInfo != null ? mixerInfo.toString() : null,
                ctrlDevice != null ? ctrlDevice.toString() : null,
                cfgShowPanel);
    }

    private static Preferences getPreferenceNode() {
        return Preferences.systemNodeForPackage(CfgPreference.class);
    }

    public static CfgPreference readPreferences() {
        final Preferences root = getPreferenceNode();
        return new CfgPreference(
                root.get("gfxDevice", null),
                root.get("gfxMode", null),
                root.getBoolean("gfxFullScreen", false),
                root.get("mixerInfo", null),
                root.get("ctrlDevice", null),
                root.getBoolean("cfgShowPanel", true));
    }

    private GraphicsDevice guessGfxDevice() {
        if (gfxDevice == null) {
            return null;
        }
        final GraphicsEnvironment gfxEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
        for (GraphicsDevice gfxDev : gfxEnv.getScreenDevices()) {
            if (gfxDev.getIDstring().equals(gfxDevice)) {
                return gfxDev;
            }
        }


        return null;
    }

    private DisplayMode guessGfxMode() {
        if (gfxMode == null) {
            return null;
        }
        final GraphicsDevice device = guessGfxDevice();
        if (device == null) {
            return null;
        }
        for (final DisplayMode mode : device.getDisplayModes()) {
            if (new CfgDisplayMode(mode).toString().equals(gfxMode)) {
                return mode;
            }
        }
        return null;
    }

    private Mixer.Info guessSfxMixer() {
        if (sfxMixer == null) {
            return null;
        }
        for (final Mixer.Info info : AudioSystem.getMixerInfo()) {
            if (info.toString().equals(sfxMixer)) {
                return info;
            }
        }
        return null;
    }

    private Controller guessController() {
        if (ctrlDevice == null) {
            return null;
        }
        for (Controller ctrl : ControllerEnvironment.getDefaultEnvironment().getControllers()) {
            if (ctrl.getType().equals(Controller.Type.STICK)
                    && ctrl.toString().equals(ctrlDevice)) {
                return ctrl;
            }
        }

        final File[] records = new File(".\\record").listFiles(new FilenameFilter() {

            public boolean accept(File dir, String name) {
                return name.endsWith(".rec");
            }
        });
        for (File i : records) {
            final Controller ctrl = new FilePlayControler(i);
            if (ctrl.toString().equals(ctrlDevice)) {
                return ctrl;
            }
        }
        return null;
    }

    public CfgResult buildResult() {
        return new CfgResult(guessGfxDevice(),
                guessGfxMode(),
                gfxFullScreen,
                guessSfxMixer(),
                guessController(),
                cfgShowPanel,
                null);
    }

    public void store() throws BackingStoreException {
        final Preferences root = getPreferenceNode();
        root.put("gfxDevice", gfxDevice);
        root.put("gfxMode", gfxMode);
        root.putBoolean("gfxFullScreen", gfxFullScreen);
        root.put("mixerInfo", sfxMixer);
        root.put("ctrlDevice", ctrlDevice);
        root.putBoolean("cfgShowPanel", cfgShowPanel);
        root.flush();
    }
}
